home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Apple II Sample Code / MPW IIGS SC / SC.013.Math / math.aii < prev    next >
Encoding:
Text File  |  1990-06-24  |  31.0 KB  |  1,463 lines  |  [TEXT/MPS ]

  1. *******************************************************************************
  2. *
  3. * Math -- Version 3.0
  4. *
  5. * (C)  Copyright Apple Computer, Inc. 1988-1990
  6. * All rights reserved.
  7. *
  8. * Developer Technical Support Apple II Sample Code
  9. *
  10. * by Jim Mensch
  11. *
  12. * Sample to show how to use the Integer math and SANE tools. This program shows
  13. * 2 basic operations performed both with the integer math tools and SANE. The
  14. * first is the calculation and display of a simple SINE curve. The second is
  15. * a more complex Fast Fourier Transform.
  16. *
  17. *******************************************************************************
  18.     eject
  19.     
  20. **********************************************************************
  21. *                                                                    *
  22. *     This program and its derivatives are licensed only for         *
  23. *     use on Apple computers.                                        *
  24. *                                                                    *
  25. *     Works based on this program must contain and                   *
  26. *     conspicuously display this notice.                             *
  27. *                                                                    *
  28. *     This software is provided for your evaluation and to           *
  29. *     assist you in developing software for the Apple IIGS           *
  30. *     computer.                                                      *
  31. *                                                                    *
  32. *     DISCLAIMER OF WARRANTY                                         *
  33. *                                                                    *
  34. *     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
  35. *     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
  36. *     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
  37. *     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
  38. *     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
  39. *     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
  40. *     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
  41. *     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
  42. *     REPAIR OR CORRECTION.                                          *
  43. *                                                                    *
  44. *     Apple does not warrant that the functions                      *
  45. *     contained in the Software will meet your requirements          *
  46. *     or that the operation of the Software will be                  *
  47. *     uninterrupted or error free or that defects in the             *
  48. *     Software will be corrected.                                    *
  49. *                                                                    *
  50. *     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
  51. *     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
  52. *     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
  53. *     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
  54. *     WHICH VARY FROM STATE TO STATE.                                *
  55. *                                                                    *
  56. *                                                                    *
  57. **********************************************************************
  58.     eject
  59.     
  60.     case   on
  61.     PRINT  NOHDR,NOGEN
  62.     STRING AsIS
  63.  
  64.     PRINT PUSH,OFF
  65.     INCLUDE 'M16.Util'
  66.     INCLUDE 'M16.ProDOS'
  67.     INCLUDE 'M16.QDAux'
  68.     INCLUDE 'M16.QUICKDRAW'
  69.     Include 'E16.Quickdraw'
  70.     INCLUDE 'M16.MEMORY'
  71.     Include 'E16.Memory'
  72.     INCLUDE 'M16.EVENT'
  73.     INCLUDE 'M16.LOCATOR'
  74.     INCLUDE 'M16.MISCTOOL'
  75.     INCLUDE 'M16.TextTOOL'
  76.     INCLUDE 'M16.Menu'
  77.     INCLUDE 'M16.Control'
  78.     Include 'E16.Window'
  79.     INCLUDE 'M16.Window'
  80.     INCLUDE 'M16.Dialog'
  81.     Include 'E16.Dialog'
  82.     INCLUDE 'M16.LineEdit'
  83.     Include 'M16.List'
  84.     INCLUDE 'M16.IntMath'
  85.     INCLUDE 'M16.Scrap'
  86.     INCLUDE 'M16.Desk'
  87.     INCLUDE 'E16.SANE'
  88.     INCLUDE 'M16.SANE'
  89.  
  90. *******************************************************************************
  91. *
  92. * Math Macros
  93. *
  94. * Description:    The following macros are given to take care of some common
  95. *    operations used when you are using SANE or IntMath.
  96. *
  97. *
  98. *
  99. *******************************************************************************
  100.  
  101. ;------------------------------------------------------------------------------
  102. ;
  103. ; Copy and extended value from one variable to another
  104. ;
  105. ; ExtendEq SrcLoc,DestLoc - Copies 10 bytes from srcloc to DestLoc
  106. ;
  107. ;------------------------------------------------------------------------------
  108.     MACRO
  109.     ExtendEq &SrcLoc,&DestLoc
  110.     lda &SrcLoc
  111.     sta &DestLoc
  112.     lda &SrcLoc+2
  113.     sta &DestLoc+2
  114.     lda &SrcLoc+4
  115.     sta &DestLoc+4
  116.     lda &SrcLoc+6
  117.     sta &DestLoc+6
  118.     lda &SrcLoc+8
  119.     sta &DestLoc+8
  120.     MEND
  121.     
  122. ;-----------------------------------------------------------------------------
  123. ;
  124. ; Push a long space on the stack for fuction results
  125. ;
  126. ; LongResult
  127. ;
  128. ;-----------------------------------------------------------------------------
  129.     MACRO
  130.     LongResult
  131.     pha
  132.     pha
  133.     mend
  134.     
  135. ;-----------------------------------------------------------------------------
  136. ;
  137. ; Store 0's into an Extended number
  138. ;
  139. ; STZEXT Dest - Stores 10 bytes of 0 into Dest
  140. ;
  141. ;------------------------------------------------------------------------------
  142.     MACRO
  143.     STZEXT &Dest
  144.     stz &Dest
  145.     stz &Dest+2
  146.     stz &Dest+4
  147.     stz &Dest+6
  148.     stz &Dest+8
  149.     mend
  150.     
  151. ;------------------------------------------------------------------------------
  152. ;
  153. ; Store 0's into a longword
  154. ;
  155. ; STZL Dest - stores 4 bytes of 0 into Dest
  156. ;
  157. ;------------------------------------------------------------------------------
  158.     MACRO
  159.     STZL &Dest
  160.     stz &Dest
  161.     stz &Dest+2
  162.     mend
  163.  
  164. *******************************************************************************
  165.  
  166.     PRINT POP
  167.  
  168. DPHandle    equ 0
  169. DPPointer    equ DPHandle+4
  170. DeRef    equ DPPointer+4
  171.  
  172. ScreenWidth    equ 640
  173. ScreenMode    equ $80
  174.  
  175.     EJECT
  176. *******************************************************************************
  177. *
  178. Math    PROC
  179. *
  180. * Description:    This main routine calls the other major routines in the 
  181. *    correct order.
  182. *
  183. *
  184. * Inputs:    None
  185. *
  186. * Outputs:    None
  187. *
  188. * External Refs:
  189.     Import QuitParms
  190.     Import InitTools
  191.     Import InitApp
  192.     Import EventLoop
  193.     Import CloseTools
  194.     Import CloseApp
  195. *
  196. * Entry Points:    None
  197. *
  198. *******************************************************************************
  199.  
  200.     jsr InitTools
  201.     jsr InitApp
  202.  
  203.     _ShowCursor
  204.  
  205.     jsr EventLoop
  206.     jsr CloseApp
  207.     jsr CloseTools
  208.  
  209.     _Quit QuitParms
  210.  
  211.     EndP
  212.  
  213.     EJECT
  214. *******************************************************************************
  215. *
  216. Globals    RECORD
  217. *
  218. * Description:    Global data for use in all routines of this demo. This area
  219. *    also contains the data used by StandardLib.aii    
  220. *
  221. *
  222. * Inputs:    None
  223. *
  224. * Outputs:    None
  225. *
  226. * External Refs:
  227.     import displayCache
  228. *
  229. * Entry Points:
  230.     export QuitParms    ; used by Main
  231. *
  232. *******************************************************************************
  233. *
  234. * Standard global data
  235. *
  236. *******************************************************************************
  237.  
  238. TitleString    str 'Apple IIgs Integer Math/Sane demo'
  239. AutString    str 'By Jim Mensch Apple DTS -- Version: 3.0'
  240. VersString    str 'Copyright (c) 1988-1990 Apple Computer'
  241.  
  242.  
  243. MenuHeight    ds.B 2    ; Stored height of menu bar
  244. MyID    ds.B 2    ; Application ID
  245. MyDP    ds.B 2    ; My direct page storage
  246.  
  247. QuitFlag    ds.B 2
  248. QuitParms    dc.L 0    ; Pathname of next app
  249.     dc.W $00    ; flags
  250.  
  251. EventRecord
  252. EventWhat    ds.B 2
  253. EventMessage    ds.B 4
  254. EventWhen    ds.B 4
  255. EventWhere    ds.B 4
  256. EventModifiers    ds.B 2
  257. TaskData    ds.B 4
  258. TaskMask    dC.L $0000FFFF
  259.  
  260. portCacheInfo    ds.b 4
  261.     ds.b 4
  262.     ds.b 4
  263.     ds.b 4
  264.     dc.w $C000
  265.     dc.w 0,0,175,599
  266.     dc.w 0,0,175,599
  267.  
  268.     EJECT
  269. *******************************************************************************
  270. *
  271. * Application specific global data
  272. *
  273. *******************************************************************************
  274.  
  275. ; This is a list of pointers to the text that is used to create our menus. It
  276. ; is used by InitApp to find all of the menu templates and use them to create
  277. ; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
  278. ; corresponding menu template pointer in this table, and uses that in a
  279. ; NewMenu call. It then decrements the index by 4, and repeats the procees
  280. ; until the index is negative.
  281.  
  282. MenuPtr    dc.l AppMenu
  283.     dc.l FileMenu
  284. MenuPtrLen    equ *-MenuPtr
  285.  
  286.  
  287. ; Menu list: menu items should be numbered consecutivly starting from 250.
  288. ; As a convention, use 256 as about and 257 as Quit.
  289.  
  290.  
  291.  
  292. AppMenu    dc.B '$$@\XN1',$0D
  293.     dc.B '--About Math...\N256V',$00
  294.     dc.B '.'
  295. FileMenu    dc.B '$$ File \N2',$0D
  296.     dc.B '--SANE Fast Fourier transform\N260',$00
  297.     dc.B '--Integer Fast Fourier transform\N261',0
  298.     dc.B '--Integer Sine wave\N258*Ii',$00
  299.     dc.B '--SANE Sine wave\N259*SsV',$00
  300.     dc.B '--Quit\N257*Qq',$00
  301.     dc.B '.'
  302.  
  303. ; Paramater block used to create the main window for display. All the
  304. ; graphing routines will use this window to draw into.
  305.  
  306. MyWindow    dc.W WindEnd-*    ; size of paramBlock
  307.     dc.W %0010000000100000 ; frame bits : alert, vis
  308.     dc.L 0    ; no title bar, no title...
  309.     dc.L 0    ; ref con 0
  310.     dc.W 0,0,0,0    ; zoomed rect
  311.     dc.L 0    ; color table = default
  312.     dc.W 0,0    ; scroll bar XY origin
  313.     dc.W 0,0    ; no scroll no max...
  314.     dc.W 0,0    ; No zooming...
  315.     dc.W 0,0    ; no scrolling
  316.     dc.W 0,0    ; no paging....
  317.     dc.L 0    ; no info bar, no ref con
  318.     dc.W 0    ; info bar height (    none...)
  319.     dc.L 0    ; Frame defproc, NIL=standard
  320.     dc.L 0    ; no info bar def proc
  321.     dc.L displayCache    ; update procedure to display cache
  322.     dc.W 20,20,195,619    ; bounds rect...
  323.     dc.L $FFFFFFFF    ; plane= on top...
  324.     dc.L 0    ; NIL storage pointer
  325. WindEnd    equ *
  326. ContRect    dc.W 0,0,180,599    ; content rectangle
  327.  
  328. WindPointer    ds.B 4
  329.  
  330. ; Constants used thru the program both represent PI*2
  331.  
  332. TwoPi    dc.b $1D,$72,$33,$DC,$80,$CF,$0F,$C9,$01,$40
  333. TwoPiFix    dc.W $487E,$0006
  334.  
  335. ; Titles for the bottom of the window
  336.  
  337. IntSineTitle    str 'Integer Math Demo: plotting Y=SIN(X)'
  338. SANESineTitle    str 'SANE Demo: plotting Y=SIN(X)'
  339. IntHarmTitle    str 'Integer Math Demo: plotting complex waveform'
  340. SANEHarmTitle    str 'SANE Demo: plotting complex waveform'
  341.     EndR
  342.     
  343.     EJECT
  344. *******************************************************************************
  345. *
  346. InitApp    PROC
  347. *
  348. * Description:    This routine creates our window and zeros out the quitflag
  349. *
  350. *
  351. * Inputs:    None
  352. *
  353. * Outputs:    None
  354. *
  355. * External Refs:
  356.     Import newPort
  357. *
  358. * Entry Points:    None
  359. *
  360. *******************************************************************************
  361.     With Globals
  362.  
  363.     Stz QuitFlag    ; zero out quit flag
  364.  
  365.     PushLong #0
  366.     PushLong #MyWindow
  367.     _NewWindow    ; create a window to graph in
  368.     PullLong WindPointer
  369.  
  370.     PushLong WindPointer
  371.     _SetPort    ; make the new window the current port
  372.  
  373.     pha
  374.     pha
  375.     pea portCacheInfo>>16
  376.     pea portCacheInfo
  377.     jsl newPort
  378.     pla    ; The result is also stored in portCacheInfo.
  379.     pla
  380.  
  381.     rts
  382.     EndP
  383.  
  384.     EJECT
  385. *******************************************************************************
  386. *
  387. CloseApp    PROC
  388. *
  389. * Description:    This routine will be called at program end to dispose of
  390. *    the window.
  391. *
  392. *
  393. * Inputs:    None
  394. *
  395. * Outputs:    None
  396. *
  397. * External Refs:
  398.     Import killPort
  399. *
  400. * Entry Points:    None
  401. *
  402. *******************************************************************************
  403.     With Globals
  404.  
  405.     PushLong WindPointer
  406.     _CloseWindow
  407.  
  408.     pea portCacheInfo>>16
  409.     pea portCacheInfo
  410.     jsl killPort
  411.  
  412.     rts
  413.     EndP
  414.  
  415.     EJECT
  416. *******************************************************************************
  417. *
  418. EventLoop    PROC
  419. *
  420. * Description:    Main loop. Handles events until the user selects quit
  421. *
  422. *
  423. * Inputs:    None
  424. *
  425. * Outputs:    None
  426. *
  427. * External Refs:
  428.     Import Ignore
  429.     Import MenuSelect
  430. *
  431. * Entry Points:
  432. *
  433. *******************************************************************************
  434.     With Globals
  435.  
  436.  
  437.     pha    ; Push on space for TaskMaster result
  438.     PushWord #$FFFF    ; GetNextEvent mask
  439.     PushLong #EventRecord ; Pointer to Event Record
  440.     _TaskMaster
  441.  
  442.     pla    ; Get TaskMaster result
  443.     beq EventLoop    ; Remove if you want to use null events
  444.     asl A    ; Turn it into an index
  445.     tax
  446.     jsr (TaskTable,x)    ; Call appropriate event handler
  447.  
  448.     lda QuitFlag    ; Quit selected?
  449.     beq EventLoop    ; no - keep looping
  450.  
  451.     rts    ; yes- leave the program
  452.  
  453.  
  454. TaskTable    dc.W Ignore    ; 0 Null
  455.     dc.W Ignore    ; 1 MouseDown
  456.     dc.W Ignore    ; 2 Mouse Up
  457.     dc.W Ignore    ; 3 KeyDown
  458.     dc.W Ignore    ; 4 Undefined
  459.     dc.W Ignore    ; 5 AutoKey
  460.     dc.W Ignore    ; 6 Update
  461.     dc.W Ignore    ; 7 undefined
  462.     dc.W Ignore    ; 8 activate
  463.     dc.W Ignore    ; 9 Switch
  464.     dc.W Ignore    ; 10 desk acc
  465.     dc.W Ignore    ; 11 device driver
  466.     dc.W Ignore    ; 12 ap
  467.     dc.W Ignore    ; 13 ap
  468.     dc.W Ignore    ; 14 ap
  469.     dc.W Ignore    ; 15 ap
  470.     dc.W Ignore    ; TASK 0 indesk
  471.     dc.W MenuSelect    ; TASK 1 in menuBar
  472.     dc.W Ignore    ; TASK 2 in system window
  473.     dc.W Ignore    ; TASK 3 in content
  474.     dc.W Ignore    ; TASK 4 in Drag
  475.     dc.W Ignore    ; TASK 5 in grow
  476.     dc.W Ignore    ; TASK 6 in goaway
  477.     dc.W Ignore    ; TASK 7 in zoom
  478.     dc.W Ignore    ; TASK 8 in info bar
  479.     dc.W Ignore    ; TASK 9 in special    menu
  480.     dc.W Ignore    ; TASK 10 in NDA
  481.     dc.W Ignore    ; TASK 11 in frame
  482.     dc.W Ignore    ; TASK 12 in drop            
  483.  
  484.     EndP
  485.     
  486.     EJECT
  487. *******************************************************************************
  488. *
  489. MenuSelect    PROC
  490. *
  491. * Description:    This routine is called when taskmaster returns a code
  492. *    indicating that the user selected one of our menu options.
  493. *    This routine will call whatever routine is indicated for
  494. *    each menu action
  495. *
  496. *
  497. * Inputs:    TaskData - menu selected by the user
  498. *
  499. * Outputs:    None
  500. *
  501. * External Refs:
  502.     Import Ignore
  503.     Import doAbout
  504.     Import doQuit
  505.     Import IntSineCurve
  506.     Import SANESineCurve
  507.     Import IntHarmWave
  508.     Import SANEHarmWave
  509. *
  510. * Entry Points:
  511. *
  512. *******************************************************************************
  513.     With Globals
  514.  
  515.     lda TaskData    ; get the ID of the menu item selected
  516.     sec    ; adjust it to be between 0 and 5
  517.     sbc #256
  518.     asl a    ; multiply it by 2
  519.     tax    ; and use it as an index into our jump
  520.     jsr (MenuTable,x)    ; table.
  521.  
  522. MSDone
  523.     PushWord #0    ; menu action complete, unhilite the
  524.     PushWord TaskData+2    ; selected menu to show we are done
  525.     _HiliteMenu
  526.  
  527.     rts    ; and quit
  528.  
  529. MenuTable    dc.W doAbout    ; about shell...
  530.     dc.W doQuit    ; quit selected
  531.     dc.W IntSineCurve    ; draw integer math    sine wave
  532.     dc.W SANESineCurve    ; draw sane sine wave
  533.     dc.W SANEHarmWave
  534.     dc.W IntHarmWave
  535.     EndP
  536.  
  537.     EJECT
  538. *******************************************************************************
  539. *
  540. doQuit    PROC
  541. *
  542. * Description:    Sets the quit flag to inform the event loop that the user
  543. *    wants to stop the program
  544. *
  545. *
  546. * Inputs:    None
  547. *
  548. * Outputs:    None
  549. *
  550. * External Refs:    None
  551. *
  552. * Entry Points:    None
  553. *
  554. *******************************************************************************
  555.     With Globals
  556.  
  557.     lda #$FFFF
  558.     sta QuitFlag
  559.     rts
  560.     EndP
  561.  
  562. *******************************************************************************
  563. *
  564. Ignore    PROC
  565. *
  566. * Description:    Called when the program gets an event or menu selection that
  567. *    it does not want to handle
  568. *
  569. *
  570. * Inputs:    None
  571. *
  572. * Outputs:    None
  573. *
  574. * External Refs:    None
  575. *
  576. * Entry Points:    None
  577. *
  578. *******************************************************************************
  579.     rts
  580.     EndP
  581.  
  582.     EJECT
  583. *******************************************************************************
  584. *
  585. setCachePort    PROC
  586.     export setViewPort, displayCache
  587.     with   Globals
  588.  
  589.     plx    ;Clone enough of the stack.
  590.     tsc
  591.     sta keepStackPtr
  592.     ldy #10
  593. aa    lda 10*2-1,s
  594.     pha
  595.     dey
  596.     bne aa
  597.     phx
  598.  
  599.     lda portCacheInfo+2    ;Switch to cache port.
  600.     pha
  601.     lda portCacheInfo
  602.     pha
  603.     _SetPort
  604.  
  605.     rts
  606.  
  607. setViewPort    plx    ;Set the stack back to before cloning.
  608.     lda keepStackPtr
  609.     tcs
  610.     phx
  611.  
  612.     lda WindPointer+2
  613.     pha
  614.     lda WindPointer
  615.     pha
  616.     _SetPort
  617.  
  618.     rts
  619.  
  620. keepStackPtr    dc.w 0
  621.  
  622. displayCache    pha
  623.     pha
  624.     _GetPort
  625.  
  626.     lda portCacheInfo+2
  627.     pha
  628.     lda portCacheInfo
  629.     pha
  630.     _SetPort
  631.  
  632.     pea cacheLocInfo>>16
  633.     pea cacheLocInfo
  634.     _GetPortLoc
  635.  
  636.     pea cachePortRect>>16
  637.     pea cachePortRect
  638.     _GetPortRect
  639.  
  640.     _SetPort
  641.  
  642.     pea cacheLocInfo>>16
  643.     pea cacheLocInfo
  644.     pea cacheBoundsRect>>16
  645.     pea cacheBoundsRect
  646.     lda #0
  647.     pha
  648.     pha
  649.     pha
  650.     _PPToPort
  651.     rtl
  652.  
  653. cacheLocInfo    ds.b 8
  654. cacheBoundsRect    ds.b 8
  655. cachePortRect    ds.b 8
  656.  
  657.     endp
  658. *
  659. *******************************************************************************
  660.  
  661.  
  662.  
  663. *******************************************************************************
  664. *
  665. IntSineCurve    PROC
  666. *
  667. * Description:    This routine will calculate a simple Sine curve and display
  668. *    it graphically on the screen.    
  669. *
  670. *
  671. * Inputs:    None
  672. *
  673. * Outputs:    None
  674. *
  675. * External Refs:    None
  676. *
  677. * Entry Points:    None
  678. *
  679. *******************************************************************************
  680.     With Globals
  681.  
  682.     _WaitCursor
  683.  
  684.     PushLong #ContRect    ; first, start with a clean screen
  685.     jsr setCachePort    ; by erasing the old screen
  686.     _EraseRect
  687.     jsr setViewPort
  688.     _EraseRect
  689.  
  690.     PushWord #10    ; label the bottom of the window
  691.     PushWord #170    ; to show what we are doing
  692.     jsr setCachePort
  693.     _MoveTo
  694.     jsr setViewPort
  695.     _MoveTo
  696.  
  697.     PushLong #IntSineTitle
  698.     jsr setCachePort
  699.     _DrawString
  700.     jsr setViewPort
  701.     _DrawString
  702.  
  703.     stzL LoopCount    ; zero the counter to start this thing
  704.  
  705.     PushWord #0    ; start this drawing off
  706.     PushWord #80
  707.     jsr setCachePort
  708.     _MoveTo
  709.     jsr setViewPort
  710.     _MoveTo
  711.  
  712.  
  713. DIMLoop
  714.     LongResult    ; space for results    here for all the
  715.     LongResult    ; following calculations. by pushing
  716.     LongResult    ; the space here, we do not need to 
  717.     LongResult    ; adjust the stack between int math calls
  718.     LongResult    ; and we save time and space
  719.     
  720.     PushLong LoopCount    ; Calc: LoopCount/180
  721.     PushLong One80    ; 
  722.     _FixDiv    ; leave result on stack for next calc
  723.         
  724.     PushLong RFixPi    ; Calc (LoopCount/180)*PI
  725.     _FixMul    ; to convert LoopCount to radians
  726.     
  727.     _FracSin    ; take the sine of the counter
  728.     
  729.     _Frac2Fix    ; convert it back to fixed #
  730.     
  731.     PushLong Eighty    ; multiply it by 80 to scale
  732.     _FixMul    ; we have our number!
  733.     PullLong YCord    ; and its the y coordinate
  734.  
  735.     PushWord LoopCount+2 ; X coordinate (HiWord of Fixed)
  736.     lda YCord+2    ; Y coordinate + 80
  737.     clc    ; to scale the number between
  738.     adc #80    ; 0 and 160
  739.     pha
  740.     jsr setCachePort
  741.     _LineTo    ; draw the linesegment for this point
  742.     jsr setViewPort
  743.     _LineTo
  744.  
  745.     inc LoopCount+2    ; bump the loopcounter
  746.     lda LoopCount+2    ; and see if we have reached 360
  747.     cmp #360    ; for a full SINE curve
  748.     bge DIMDone    ; if so, then finish the loop
  749.     brl DIMLoop    ; if not do the next iteration
  750.  
  751. DIMDone    _InitCursor
  752.     rts    ; finish the routine
  753.  
  754. LoopCount    ds.B 4    ; Fixed number to store degrees
  755. One80    dc.W 0,180    ; a fixed number representing 180
  756. Eighty    dc.W 0,80    ; a FIxed number represenging 80
  757. YCord    ds.B 4    ; temp storage for the y coordinate
  758. RFixPi    dc.L $0003243F    ; 3.14159 (PI in fixed format)
  759.     EndP
  760.  
  761.     EJECT
  762. *******************************************************************************
  763. *
  764. SANESineCurve    PROC
  765. *
  766. * Description:    This routine will use the SANE toolset to calculate
  767. *    a Sine curve. It will then plot the points on the screen.
  768. *
  769. *
  770. * Inputs:    None
  771. *
  772. * Outputs:    None
  773. *
  774. * External Refs:    None
  775. *
  776. * Entry Points:    None
  777. *
  778. *******************************************************************************
  779.     With Globals
  780.  
  781.     _WaitCursor
  782.  
  783.     PushLong #ContRect    ; first, start with a clean screen
  784.     jsr setCachePort    ; by erasing the old screen
  785.     _EraseRect
  786.     jsr setViewPort
  787.     _EraseRect
  788.  
  789.     PushWord #10    ; label the bottom of the window
  790.     PushWord #170    ; to show what we are doing
  791.     jsr setCachePort
  792.     _MoveTo
  793.     jsr setViewPort
  794.     _MoveTo
  795.  
  796.     PushLong #SANESineTitle
  797.     jsr setCachePort
  798.     _DrawString
  799.     jsr setViewPort
  800.     _DrawString
  801.     
  802.     PushWord #0    ; start this drawing off
  803.     PushWord #80    ; in the middle of the screen
  804.     jsr setCachePort
  805.     _MoveTo
  806.     jsr setViewPort
  807.     _MoveTo
  808.     
  809.     stz LoopCount
  810.  
  811. DSaneLoop
  812.     ExtendEq SanePi,TempResult ; move pi/180 into the result
  813.  
  814.     PushLong #LoopCount    ; convert LoopCount to Radians
  815.     PushLong #TempResult
  816.     FMULI    ; by multiplying by pi/180
  817.  
  818.     PushLong #TempResult
  819.     FSINX    ; now get the SINE of it
  820.  
  821.     PushLong #Eighty    ; multiply by 80
  822.     PushLong #TempResult
  823.     FMULI
  824.  
  825.     PushLong #TempResult
  826.     PushLong #YCord    ; convert to an Integer
  827.     FX2I
  828.  
  829.     PushWord LoopCount    ; X coordinate
  830.     lda YCord    ; Y coordinate + 80
  831.     clc    ; to get a number between 
  832.     adc #80    ; 0 and 160
  833.     pha
  834.     jsr setCachePort    ; draw the line segement
  835.     _LineTo
  836.     jsr setViewPort
  837.     _LineTo
  838.  
  839.     inc LoopCount    ; bump the counter
  840.     lda LoopCount
  841.     cmp #360    ; and see if we have done all 360 degrees
  842.     bge DSaneDone    ; if so then end
  843.     brl DSaneLoop    ; if not, get next value
  844.  
  845. DSaneDone    _InitCursor
  846.     rts
  847.  
  848. LoopCount    ds.B 4
  849. SanePi    dc.B $AE,$C8,$E9,$94,$12,$35,$FA,$8E,$F9,$3F ; pi/180 ...
  850. TempResult    ds.B 10
  851. Eighty    dc.L 80
  852. YCord    ds.B 4
  853.     EndP
  854.  
  855.  
  856.     EJECT
  857. *******************************************************************************
  858. *
  859. FFTransData    Record
  860. *
  861. * Description:    Data used by both FFT calculation routines
  862. *
  863. *
  864. * Inputs:    None
  865. *
  866. * Outputs:    None
  867. *
  868. * External Refs:    None
  869. *
  870. * Entry Points:    None
  871. *
  872. *******************************************************************************
  873.  
  874. FixCount    dc.W 0    ; fractional portsion of our
  875. Count    ds.B 2    ; fixed point counter
  876. LoopCount    ds.B 2
  877. FixSamp    dc.W 0    ; fractional portion of the sample var
  878. Sample    ds.B 2    ; sample to figure for
  879. FixMaxSamp    dc.W 0    ; fractional portion of Max Sample
  880. MaxSample    dc.W 256    ; maximum number of    samples
  881. MaxHarm    dc.W 6    ; maximum number of harmonics
  882. MaxValue    ds.B 10    ; maximum vaule of the FFT
  883. AmpTbl    dc.W 0,10,8,6,4,2,1    ; amplitudes of each harmonic
  884. PhaseTbl    dc.W 0,1,2,4,6,8,10    ; high word of each fixed phase
  885. PhaseTblF    dc.L 0,6554,13107,26214,39321,52428,$FFFF
  886. TempValue    ds.B 10    ; intermediate result storage
  887. TempFactor    ds.B 10
  888. Temp1    ds.B 10
  889. Temp2    ds.B 10
  890. FFTWave    ds.B 2560    ; table to hold intermediate values
  891. MyDecForm    dc.W 1
  892.     dc.W 8    ; 8 digits after the decimal place
  893. TempI    ds.B 2
  894. TempF    ds.B 4
  895. Const127    dc.W 79
  896. Const80Fix    dc.L $004F000
  897. Const10    dc.W 10
  898.     EndR
  899.  
  900.  
  901.     EJECT
  902. *******************************************************************************
  903. *
  904. SANEHarmWave    proc
  905. *
  906. * Description:    Create a complex harmonic wave using SANE
  907. *
  908. *
  909. * Inputs:    None
  910. *
  911. * Outputs:    None
  912. *
  913. * External Refs:
  914.     Import SaneFFTIteration
  915.     Import doNormIter
  916. *
  917. * Entry Points:
  918. *
  919. *******************************************************************************
  920.  
  921.     With Globals
  922.     With FFTransData
  923.  
  924.     _WaitCursor
  925.  
  926.     PushLong #ContRect    ; first, start with a clean screen
  927.     jsr setCachePort    ; by erasing the old screen
  928.     _EraseRect
  929.     jsr setViewPort
  930.     _EraseRect
  931.  
  932.     PushWord #10    ; label the bottom of the window
  933.     PushWord #170    ; to show what we are doing
  934.     jsr setCachePort
  935.     _MoveTo
  936.     jsr setViewPort
  937.     _MoveTo
  938.     
  939.     PushLong #SANEHarmTitle
  940.     jsr setCachePort
  941.     _DrawString
  942.     jsr setViewPort
  943.     _DrawString
  944.     
  945.  
  946.     PushWord #0    ; start this drawing off
  947.     PushWord #80    ; at the left edge
  948.     jsr setCachePort
  949.     _MoveTo
  950.     jsr setViewPort
  951.     _MoveTo
  952.  
  953.     stz Sample    ; and zero out all global values
  954.     STZEXT MaxValue
  955.     STZEXT Temp1
  956.     STZEXT Temp2
  957.     STZEXT TempFactor
  958.  
  959. DHWLoop1    jsr SaneFFTIteration ; do one iteration
  960.  
  961.     lda Sample    ; now save tempValue into our array
  962.     asl a    ; multiply by 2
  963.     sta Temp1    ; and save it for a    sec
  964.     asl a
  965.     asl a    ; multiply by 8
  966.     clc
  967.     adc Temp1    ; x*8+x*2=x*10
  968.     tax    ; use as an index into the sample array
  969.  
  970.     lda TempValue    ; now stow the current value
  971.     sta FFTWave,x    ; into our wave table. Later this
  972.     lda TempValue+2    ; table will be normalized
  973.     sta FFTWave+2,x
  974.     lda TempValue+4
  975.     sta FFTWave+4,x
  976.     lda TempValue+6
  977.     sta FFTWave+6,x
  978.     lda TempValue+8
  979.     sta FFTWave+8,x
  980.  
  981.     inc Sample    ; bump the sample counter
  982.     lda #255
  983.     cmp Sample    ; test to see if we have reached the 
  984.     bge DHWLoop1    ; last sample, if not do the next one
  985.  
  986. ; if the last sample was reached, it is time to go thru the wavetable and
  987. ; convert all the number so they are between 0 and 160.
  988.     
  989.     stz Count    ; initialize the index
  990. DHWLoop2    inc Count
  991.     jsr doNormIter    ; normalize one iteration
  992.  
  993.     PushWord Count    ; X coordinate
  994.     PushWord TempValue    ; value returned by doNormIter
  995.     jsr setCachePort    ; draw the line
  996.     _LineTo
  997.     jsr setViewPort
  998.     _LineTo
  999.  
  1000.     lda #255    ; see if the counter has reached the max
  1001.     cmp Count    ; sample we recorded
  1002.     bge DHWLoop2    ; if not, do another point
  1003.  
  1004.  
  1005.     _InitCursor    ; if it has, then we can simply end
  1006.     rts
  1007.     EndP
  1008.     
  1009.     EJECT
  1010. *******************************************************************************
  1011. *
  1012. SaneFFTIteration    PROC
  1013. *
  1014. * Description:    This routine takes the current sample value and computes
  1015. *    all the harmonic components that make up the wave for that
  1016. *    sample.
  1017. *
  1018. *
  1019. * Inputs:    Sample - current sample to compute for
  1020. *
  1021. * Outputs:    TempValue - output sample value
  1022. *
  1023. * External Refs:
  1024. *
  1025. * Entry Points:
  1026. *
  1027. *******************************************************************************
  1028.     With Globals
  1029.     With FFTransData
  1030.  
  1031.     STZEXT TempValue
  1032.  
  1033.     PushLong #Sample
  1034.     PushLong #TempFactor
  1035.     FI2X    ; convert the max sample rate to extended
  1036.  
  1037.     PushLong #MaxSample
  1038.     PushLong #Temp1
  1039.     FI2X
  1040.  
  1041.     PushLong #Temp1
  1042.     PushLong #TempFactor
  1043.     FDIVX    ; TempFactor:=TempFactor/Temp1
  1044.  
  1045.     PushLong #TwoPi
  1046.     PushLong #TempFactor
  1047.     FMULX    ; TempFactor:=6.28318*(count/maxSample)
  1048.  
  1049.     stz Count    ; zero out the counter
  1050.  
  1051. FFLoop
  1052.     ExtendEq TwoPi,Temp2
  1053.  
  1054.     lda Count    ; get the count
  1055.     asl a    ; multiply by 2
  1056.     tax
  1057.     lda PhaseTbl,x
  1058.     sta TempI
  1059.     PushLong #TempI
  1060.     PushLong #Temp1
  1061.     FI2X    ; Temp1:=Phase[count]
  1062.  
  1063.     PushLong #Const10
  1064.     PushLong #Temp1
  1065.     FDIVI    ; divide by 10 to make it fractional
  1066.  
  1067.     PushLong #Temp1
  1068.     PushLong #Temp2
  1069.     FMulX    ; Temp2:=(Temp1)/10*TwoPi
  1070.  
  1071.     ExtendEq TempFactor,Temp1
  1072.  
  1073.     PushLong #Count
  1074.     PushLong #Temp1
  1075.     FMULI    ; tempi:=count*TempFactor
  1076.  
  1077.     PushLong #Temp2
  1078.     PushLong #Temp1
  1079.     FADDX    ; Temp1:=((count*TempFactor)+(6.28318*Phase[count]))
  1080.  
  1081.     PushLong #Temp1
  1082.     FCOSX    ; Temp1:=Cos(Temp1)
  1083.  
  1084.     lda Count    ; get the count
  1085.     asl a    ; multiply by 2
  1086.     tax
  1087.     lda AmpTbl,x
  1088.     sta TempI
  1089.     PushLong #TempI
  1090.     PushLong #Temp1
  1091.     FMULI    ; Temp1:=Temp1*Amp[count]
  1092.  
  1093.     PushLong #Temp1
  1094.     PushLong #TempValue
  1095.     FADDX    ; finally tempValue:=tempValue+Temp1
  1096.  
  1097.     PushLong #TempValue
  1098.     PushLong #Temp1
  1099.     FX2X    ; copy tempvalue into Temp1
  1100.  
  1101.     PushLong #Temp1
  1102.     FABSX
  1103.  
  1104.     PushLong #Temp1
  1105.     PushLong #MaxValue
  1106.     FCMPX    ; now update the max value if needed
  1107.  
  1108.     FBLE FFTL010    ; if the new number    <= old max ignore next line
  1109.  
  1110.     ExtendEq Temp1,MaxValue
  1111.  
  1112. FFTL010
  1113.     inc Count
  1114.     lda Count
  1115.     cmp MaxHarm    ; are we done yet???
  1116.     bge FFTDone
  1117.     brl FFLoop
  1118. FFTDone    rts
  1119.     EndP
  1120.  
  1121.     EJECT
  1122. *******************************************************************************
  1123. *
  1124. doNormIter    Proc
  1125. *
  1126. * Description:    Normalize one iteration of the wavetable. This routine
  1127. *    takes the current sample value and converts it to 
  1128. *
  1129. *
  1130. * Inputs:    Count - current sample number
  1131. *
  1132. * Outputs:    TempValue - the normalized value
  1133. *
  1134. * External Refs:    None
  1135. *
  1136. * Entry Points:    None
  1137. *
  1138. *******************************************************************************
  1139.     With Globals
  1140.     With FFTransData
  1141.  
  1142.     lda Count
  1143.     asl a    ; multiply by 2
  1144.     sta Temp1    ; and save it for a    sec
  1145.     asl a
  1146.     asl a    ; multiply by 8
  1147.     clc
  1148.     adc Temp1    ; x*8+x*2=x*10
  1149.     tax
  1150.  
  1151.     lda FFTWave,x    ; now load the current value
  1152.     sta TempValue
  1153.     lda FFTWave+2,x
  1154.     sta TempValue+2
  1155.     lda FFTWave+4,x
  1156.     sta TempValue+4
  1157.     lda FFTWave+6,x
  1158.     sta TempValue+6
  1159.     lda FFTWave+8,x
  1160.     sta TempValue+8
  1161.  
  1162.     ExtendEq MaxValue,Temp2
  1163.  
  1164.     PushLong #Temp2
  1165.     PushLong #TempValue    ; divide the two
  1166.     FDIVX
  1167.  
  1168.     PushLong #Const127    ; now scale it
  1169.     PushLong #TempValue
  1170.     FMULI
  1171.  
  1172.     PushLong #Const127
  1173.     PushLong #TempValue
  1174.     FADDI
  1175.  
  1176.     PushLong #TempValue    ; now, convert ot to an integer
  1177.     PushLong #TempI
  1178.     FX2I
  1179.  
  1180.     lda TempI
  1181.     sta TempValue
  1182.     rts
  1183.     EndP
  1184.  
  1185.  
  1186.  
  1187.     EJECT
  1188. *******************************************************************************
  1189. *
  1190. IntHarmWave    PROC
  1191. *
  1192. * Description:    This routine will create a complex waveformusing the 
  1193. *    integer math tools
  1194. *
  1195. *
  1196. * Inputs:    None
  1197. *
  1198. * Outputs:    None
  1199. *
  1200. * External Refs:
  1201.     Import IntFFTIteration
  1202.     Import IntHarmI
  1203. *
  1204. * Entry Points:
  1205. *
  1206. *******************************************************************************
  1207.     With Globals
  1208.     With FFTransData
  1209.  
  1210.     _WaitCursor
  1211.  
  1212.     PushLong #ContRect    ; first, start with a clean screen
  1213.     jsr setCachePort    ; by erasing the old screen
  1214.     _EraseRect
  1215.     jsr setViewPort
  1216.     _EraseRect
  1217.  
  1218.     PushWord #10    ; label the bottom of the window
  1219.     PushWord #170    ; to show what we are doing
  1220.     jsr setCachePort
  1221.     _MoveTo
  1222.     jsr setViewPort
  1223.     _MoveTo
  1224.     
  1225.     PushLong #IntHarmTitle
  1226.     jsr setCachePort
  1227.     _DrawString
  1228.     jsr setViewPort
  1229.     _DrawString
  1230.     
  1231.     PushWord #0    ; start this drawing off
  1232.     PushWord #80
  1233.     jsr setCachePort
  1234.     _MoveTo
  1235.     jsr setViewPort
  1236.     _MoveTo
  1237.  
  1238.     stz Sample    ; zero out some starting values
  1239.     STZL MaxValue
  1240.     STZL Temp1
  1241.     STZL Temp2
  1242.     STZL TempFactor
  1243.  
  1244.  
  1245. DIWLoop1    jsr IntFFTIteration    ; do one iteration of the wave
  1246.  
  1247.     lda Sample    ; now save tempValue into our array
  1248.     asl a    ; multiply by 2
  1249.     asl a
  1250.     tax
  1251.  
  1252.     lda TempValue    ; now stow the temp    value
  1253.     sta FFTWave,x    ; into an array for later use
  1254.     lda TempValue+2
  1255.     sta FFTWave+2,x
  1256.  
  1257.     inc Sample    ; bump the sample counter
  1258.     lda #255    
  1259.     cmp Sample    ; see if we are done
  1260.     bge DIWLoop1    ; if not, get another sample
  1261.  
  1262. ; Now that the array of values has been created. Go thru and scale
  1263. ; each value so that it fits in our wave and is between 0 and 160
  1264.  
  1265.     stz Count    ; zero the sample counter
  1266. DIWLoop2    inc Count
  1267.     jsr IntHarmI    ; normalize one iteration
  1268.  
  1269.     PushWord Count    ; X coordinate
  1270.     PushWord TempValue
  1271.     jsr setCachePort    ; draw the line
  1272.     _LineTo
  1273.     jsr setViewPort
  1274.     _LineTo
  1275.  
  1276.     lda #255
  1277.     cmp Count
  1278.     bge DIWLoop2
  1279.  
  1280.     _InitCursor
  1281.     rts
  1282.     EndP
  1283.  
  1284.     EJECT
  1285. *******************************************************************************
  1286. *
  1287. IntFFTIteration    PROC
  1288. *
  1289. * Description:    This routine will calculate one single iteration of the 
  1290. *    wave. It will add a the Cosine*amp of each desired
  1291. *    harmonic to create a single sample
  1292. *
  1293. *
  1294. * Inputs:    None
  1295. *
  1296. * Outputs:    None
  1297. *
  1298. * External Refs:
  1299. *
  1300. * Entry Points:
  1301. *
  1302. *******************************************************************************
  1303.     With Globals
  1304.     With FFTransData
  1305.  
  1306.     stzL TempValue
  1307.  
  1308.     LongResult     ; push room on the stack
  1309.     LongResult     ; push room on the stack
  1310.     PushLong FixSamp    ; sample fixed number format
  1311.     PushLong FixMaxSamp    ; max sample fixed point number
  1312.     _FixDiv
  1313.  
  1314.     PushLong TwoPiFix
  1315.     _FixMul    ; now multiply the two to get theFactor
  1316.     PullLong TempFactor
  1317.  
  1318.  
  1319.     stz Count    ; zero out the counter
  1320.  
  1321. FFLoop
  1322.  
  1323.     lda Count    ; get the count
  1324.     asl a    ; multiply by 2
  1325.     asl a
  1326.     tax
  1327.     lda PhaseTblF,x
  1328.     sta TempF
  1329.     lda PhaseTblF+2,X
  1330.     sta TempF+2
  1331.  
  1332.     LongResult     ; push room on the stack
  1333.     PushLong TwoPiFix
  1334.     PushLong TempF
  1335.     _FixMul    ; Temp2:=Phase(Count)*TwoPi
  1336.     PullLong Temp2
  1337.  
  1338.     LongResult     ; push room on the stack
  1339.     PushLong FixCount
  1340.     PushLong TempFactor
  1341.     _FixMul    ; Temp1:=count*TempFactor
  1342.     PullLong Temp1
  1343.  
  1344.     lda Temp1    ; Temp2:=Temp1+Temp2
  1345.     clc
  1346.     adc Temp2
  1347.     sta Temp2
  1348.     lda Temp1+2
  1349.     adc Temp2+2
  1350.     sta Temp2+2
  1351.  
  1352.     LongResult     ; push room on the stack
  1353.     LongResult     ; push room on the stack
  1354.     LongResult     ; push room on the stack
  1355.     PushLong Temp2
  1356.     _FracCos    ; Temp2:=Cos(Temp2)
  1357.     _Frac2Fix    ; convert back to fixed!
  1358.     PullLong Temp2
  1359.  
  1360.     PushLong Temp2
  1361.     lda Count    ; get the count
  1362.     asl a    ; multiply by 2
  1363.     tax
  1364.     lda AmpTbl,x
  1365.     pha
  1366.     pea $0    ; Low word of fixed    count
  1367.     _FixMul    ; Temp1:=Temp1*Amp[count]
  1368.     PullLong Temp2
  1369.  
  1370.     lda TempValue    ; now add it to tempValue
  1371.     clc
  1372.     adc Temp2
  1373.     sta TempValue
  1374.     sta Temp2
  1375.     lda TempValue+2
  1376.     adc Temp2+2
  1377.     sta TempValue+2    ; Now test for max value
  1378.     sta Temp2+2
  1379.     bpl TestHigh    ; number is positive, test for high
  1380.     lda #0    ; Negate this number to get absolute value
  1381.     sec
  1382.     sbc Temp2    ; negate this number
  1383.     sta Temp2
  1384.     lda #0
  1385.     sbc Temp2+2
  1386.     sta Temp2+2
  1387. TestHigh    lda Temp2+2
  1388.     cmp MaxValue+2    ; is it bigger than    max value+2?
  1389.     beq FFTTestLow    ; if equal test the    low byte
  1390.     bge FFTStoreMax    ; if greater move it to high
  1391.     bra FFTL010
  1392. FFTTestLow    lda Temp2
  1393.     cmp MaxValue    ; is it bigger?
  1394.     blt FFTL010
  1395. FFTStoreMax    lda Temp2+2
  1396.     sta MaxValue+2
  1397.     lda Temp2
  1398.     sta MaxValue
  1399.  
  1400. FFTL010
  1401.     inc Count
  1402.     lda Count
  1403.     cmp MaxHarm    ; are we done yet???
  1404.     bge FFTDone
  1405.     brl FFLoop
  1406. FFTDone    rts
  1407.     EndP
  1408.  
  1409.     EJECT
  1410. *******************************************************************************
  1411. *
  1412. IntHarmI    PROC
  1413. *
  1414. * Description:    Takes an iteration of the wave divides it by the max value
  1415. *    and multiplies it by 160 to create a valid screen location
  1416. *
  1417. *
  1418. * Inputs:    None
  1419. *
  1420. * Outputs:    None
  1421. *
  1422. * External Refs:
  1423. *
  1424. * Entry Points:
  1425. *
  1426. *******************************************************************************
  1427.     With Globals
  1428.     With FFTransData
  1429.  
  1430.     lda Count
  1431.     asl a    ; multiply by 4
  1432.     asl a
  1433.     tax
  1434.     lda FFTWave+2,x    ; push current value on stack
  1435.     sta Temp1+2
  1436.     lda FFTWave,x    ; 
  1437.     sta Temp1
  1438.  
  1439.     LongResult     ; push room on the stack
  1440.     LongResult     ; push room on the stack
  1441.     PushLong Temp1
  1442.     PushLong MaxValue    ; divide it by maxvalue
  1443.     _FixDiv
  1444.     PullLong Temp2
  1445.  
  1446.     PushLong Temp2
  1447.     PushWord #$4F
  1448.     PushWord #0    ; now scale it
  1449.     _FixMul
  1450.     PullLong Temp1
  1451.  
  1452.     lda Temp1+2
  1453.     clc
  1454.     adc #79
  1455.     sta TempValue
  1456.     rts
  1457.     EndP
  1458.  
  1459.     Include 'Math.Init.aii'
  1460.  
  1461.     END
  1462.  
  1463.